﻿using System;
using System.Web.Mvc;
using System.Configuration;
using com.IronOne.BoardAppWeb.Lang;
using com.IronOne.BoardAppWeb.Models.Entity;
using System.Collections.Generic;
using System.Linq;

namespace com.IronOne.BoardAppWeb.Controllers
{
    public class DefaultController : BaseController
    {
        public static string ProductVersion = ConfigurationManager.AppSettings["AppVersion"].ToString();
        public static string Ip = ConfigurationManager.AppSettings["IP"].ToString();

        [Authorize]
        public ActionResult Index(string fmt)
        {
            try
            {
                char[] arr1 = { '(', ' ' };
                char[] arr2 = { '.' };
                char[] arr3 = { '_' };

                string tempVer = "";
                string minIOSVersion = ConfigurationManager.AppSettings["Min_IOS_Version"];
                string[] platform = Request.UserAgent.Split(arr1[0]);

                if (platform[1].Split(arr1[1])[0].Trim() != "iPad;")
                {
                    GenException exTemp = new GenException("err", "Please use an iPad device to login to this site.");
                    ModelState.AddModelError("err", exTemp);
                }

                string[] arrX = { "OS" };
                tempVer = platform[1].Split(arrX, StringSplitOptions.None)[1].Trim();
                tempVer = tempVer.Split(arr1[1])[0].Trim();

                int orgiOSVersion = getOSVersion(tempVer, arr3);
                int iOSVersionMin = getOSVersion(minIOSVersion, arr2);

                if (!(orgiOSVersion >= iOSVersionMin) && orgiOSVersion != 0 && iOSVersionMin != 0)
                {
                    GenException exTemp = new GenException("err", "Your iOS version " + tempVer.Replace("_", ".") + " is failed to meet the minimum supporting iOS version " +
                        minIOSVersion + ". " + Resources.Please_update_your_iPad_OS_);
                    ModelState.AddModelError("err", exTemp);
                }
            }
            catch (Exception e)
            {
                EventLog.Info("882, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", Index, " + User.Identity.Name + ", " + Resources.err_882);
                ErrorLog.Error("882, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", Index, " + User.Identity.Name + ", " + e.Message + ", " + e.InnerException);
                ModelState.AddModelError("err", new GenException("err_882"));
            }

            return GetFormatView("Home/Home.aspx");
        }

        /// <summary>
        /// Action to send the hosted iPa file version
        /// </summary>
        /// <param name="fmt">XML/HTML</param>
        /// <returns></returns>
        public ActionResult GetHostedVersion(string fmt)
        {
            EventLog.Info("0, " + "EVT, " + EventStatus.Entry.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", [Parameters=(Parameter List: " + ")]");

            try
            {
                ViewData["ProductVersion"] = GetProductVersion();
                EventLog.Info("0, " + "EVT, " + EventStatus.Success.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", Successfully generated product version.");
            }
            catch (Exception e)
            {
                EventLog.Info("881, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", " + Resources.err_881);
                ErrorLog.Error("881, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", " + e.Message + ", " + e.InnerException);
                ModelState.AddModelError("err", new GenException("err_881"));
            }
            return GetFormatView("Home/GetHostedVersion.aspx");
        }

        [NonAction]
        public static string GetProductVersion()
        {
            return ProductVersion;
        }

        [NonAction]
        public static string GetWebAppIp()
        {
            return Ip;
        }




        /// <summary>
        /// Action to send the hosted iPa file version
        /// </summary>
        /// <param name="fmt">XML/HTML</param>
        /// <returns></returns>

        [Authorize]
        public ActionResult UpdateDB(string iPaVersion, string dbVersion)
        {
            EventLog.Info("0, " + "EVT, " + EventStatus.Entry.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", [Parameters=(Parameter List: iPaVersion = " + iPaVersion + ", dbVersion = " + dbVersion + ")]");

            try
            {
                using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
                {

                    if (iPaVersion == null)
                    {
                        throw new GenException("err_881");
                    }

                    if (dbVersion == null)
                    {
                        throw new GenException("err_883");
                    }

                    ViewData["iPaVersion"] = iPaVersion;
                    ViewData["dbVersion"] = dbVersion;

                    List<iPadDB> iPadDBScripts = new List<iPadDB>();
                    List<iPadDB> iPadDBAllScripts = (from i in entities.iPadDBs
                                                     select i).ToList();

                    List<string> Versions = (from i in iPadDBAllScripts
                                             select i.Version).Distinct().ToList();


                    int minScriptNumber = 0;
                    if (!Versions.Exists(i => i == dbVersion))
                    {
                        dbVersion = GetMinExistingVersion(dbVersion, Versions);
                    }

                    if (!string.IsNullOrWhiteSpace(dbVersion))
                    {
                        minScriptNumber = (from x in iPadDBAllScripts
                                           where x.Version.Equals(dbVersion)
                                           select x.ScriptOrder).Min();

                        int maxScriptNumber = 0;
                        if (!Versions.Exists(i => i == iPaVersion))
                        {
                            iPaVersion = GetMaxExistingVersion(iPaVersion, Versions);
                        }
                        if (!string.IsNullOrWhiteSpace(iPaVersion))
                        {
                            maxScriptNumber = (from x in iPadDBAllScripts
                                               where x.Version.Equals(iPaVersion)
                                               select x.ScriptOrder).Max();

                            if (maxScriptNumber >= minScriptNumber)
                            {
                                iPadDBScripts = (from i in entities.iPadDBs
                                                 where i.ScriptOrder <= maxScriptNumber && i.ScriptOrder >= minScriptNumber
                                                 orderby i.ScriptOrder
                                                 select i).ToList();
                            }
                            else
                            {
                                ViewData["Message"] = Resources.info_ipaVersionDBVersionIssue;
                            }
                            
                        }
                        else
                        {
                            ViewData["Message"] = Resources.info_ipaVersionOutOfDateMsg;
                        }

                    }
                    else
                    {
                        ViewData["Message"] = Resources.info_dbVersionUptodateMsg;
                    }

                    int customUserId = GetLoggedUserId();
                    User user = (from u in entities.Users
                                 where u.CustomUserId == customUserId
                                 select u).FirstOrDefault();

                    ViewData["UserName"] = user.UserName;


                    EventLog.Info("0, " + "EVT, " + EventStatus.Success.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", Successfully retrived the iPad DB changes.");

                    return GetFormatView("Home/UpdateDB.aspx", iPadDBScripts);
                }
            }
            catch (GenException e)
            {
                ModelState.AddModelError("err", e);
            }
            catch (Exception e)
            {
                EventLog.Info("884, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", " + e.Message);
                ErrorLog.Error("884, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", " + e.Message + ", " + e.InnerException);
                ModelState.AddModelError("err", new GenException("err_884"));
            }
            return GetFormatView("Home/UpdateDB.aspx");
        }




        [NonAction]
        public string GetMaxExistingVersion(String iPaVersion, List<string> Versions)
        {
            String[] VersionToCompare = iPaVersion.Split('.');
            int[] clientIPAVersionToCompare = new int[VersionToCompare.Length];
            int index = 0;
            foreach (var item in VersionToCompare)
            {
                clientIPAVersionToCompare[index] = int.Parse(item);
                index++;
            }

            string maxVersion = string.Empty;
            int[] maxVersionIntArray = new int[VersionToCompare.Length];
            int[] maxClientVersionToCompare = new int[VersionToCompare.Length];
            foreach (var itemVersion in Versions) //traversing all the distinct versions in the table to find the 'FLOOR' of iPaVersion
            {
                String[] VersionFromList = itemVersion.Split('.');
                index = 0;
                bool lessThanIPAVersion = false;
                foreach (var item in VersionFromList)
                {
                    maxClientVersionToCompare[index] = int.Parse(item);
                    if (clientIPAVersionToCompare[index] > maxClientVersionToCompare[index])
                    {
                        lessThanIPAVersion = true;
                    }
                    else if (!lessThanIPAVersion && clientIPAVersionToCompare[index] < maxClientVersionToCompare[index])
                    {
                        break;
                    }

                    index++;
                }

                if (lessThanIPAVersion) //getting the FLOOR of Versions < IPAVersion
                {
                    if (!String.IsNullOrWhiteSpace(maxVersion))
                    {
                        for (int i = 0; i < VersionToCompare.Length; i++)
                        {
                            if (maxVersionIntArray[i] > maxClientVersionToCompare[i])
                            {
                                break;
                            }
                            else if (maxVersionIntArray[i] < maxClientVersionToCompare[i])
                            {
                                maxVersion = itemVersion;
                                for (int j = 0; j < VersionToCompare.Length; j++)
                                {
                                    maxVersionIntArray[j] = maxClientVersionToCompare[j];
                                }
                                break;
                            }
                        }

                    }
                    else
                    {
                        maxVersion = itemVersion;
                        for (int j = 0; j < VersionToCompare.Length; j++)
                        {
                            maxVersionIntArray[j] = maxClientVersionToCompare[j];
                        }
                    }
                }
            }

            return maxVersion;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Version"></param>
        /// <param name="Versions"></param>
        /// <returns></returns>
        [NonAction]
        public string GetMinExistingVersion(String dbVersion, List<string> Versions)
        {
            String[] VersionToCompare = dbVersion.Split('.');
            int[] clientDBVersionToCompare = new int[VersionToCompare.Length];
            int index = 0;
            foreach (var item in VersionToCompare)
            {
                clientDBVersionToCompare[index] = int.Parse(item);
                index++;
            }

            string minVersion = string.Empty;
            int[] minVersionIntArray = new int[VersionToCompare.Length];
            int[] minClientVersionToCompare = new int[VersionToCompare.Length];
            foreach (var itemVersion in Versions) //traversing all the distinct versions in the table to find the 'CEIL' of dbVersion
            {
                String[] VersionFromList = itemVersion.Split('.');
                index = 0;
                bool greaterThanDBVersion = false;
                foreach (var item in VersionFromList)
                {
                    minClientVersionToCompare[index] = int.Parse(item);
                    if (clientDBVersionToCompare[index] < minClientVersionToCompare[index])
                    {
                        greaterThanDBVersion = true;
                    }
                    else if (!greaterThanDBVersion && clientDBVersionToCompare[index] > minClientVersionToCompare[index])
                    {
                        break;
                    }

                    index++;
                }

                if (greaterThanDBVersion) //getting the CEIL of Versions > DBVersion
                {
                    if (!String.IsNullOrWhiteSpace(minVersion))
                    {
                        for (int i = 0; i < VersionToCompare.Length; i++)
                        {
                            if (minVersionIntArray[i] < minClientVersionToCompare[i])
                            {
                                break;
                            }
                            else if (minVersionIntArray[i] > minClientVersionToCompare[i])
                            {
                                minVersion = itemVersion;
                                for (int j = 0; j < VersionToCompare.Length; j++)
                                {
                                    minVersionIntArray[j] = minClientVersionToCompare[j];
                                }
                                break;
                            }
                        }

                    }
                    else
                    {
                        minVersion = itemVersion;
                        for (int j = 0; j < VersionToCompare.Length; j++)
                        {
                            minVersionIntArray[j] = minClientVersionToCompare[j];
                        }
                    }
                }
            }

            return minVersion;
        }


        /// <summary>
        /// OS version converter to an integer
        /// </summary>
        /// <param name="iOsVersion">String version</param>
        /// <param name="arr">Splitter need to apply to the iOsVersion</param>
        /// <returns>Integer number of the version</returns>
        [NonAction]
        private int getOSVersion(string iOsVersion, char[] arr)
        {
            try
            {
                string[] verArr = iOsVersion.Split(arr);
                int vPart1 = int.Parse(verArr[0].Trim());
                int vPart2 = int.Parse(verArr[1].Trim());
                int vPart3 = int.Parse(verArr[2].Trim());
                int orgiOSVersion = int.Parse(vPart1 + "" + vPart2 + "" + vPart3);
                return orgiOSVersion;
            }
            catch (Exception)
            {
                return 0;
            }
        }
    }
}
